// Function declaration
{
  function sum(x: number, y: number): number {
    return x + y;
  }

  console.log(sum(1, 2));
}

// Function expression
{
  let mySum = function (x: number, y: number): number {
    return x + y;
  };
  console.log(mySum(1, 2));
}

// interface for function
{
  interface SearchFunc {
    (src: string, search: string): boolean;
  }
  let mySearch: SearchFunc;
  mySearch = function (src: string, search: string) {
    return src.search(search) !== -1;
  };
}

// optional argument
{
  function buildName(firstName: string, lastName?: string) {
    if (lastName) {
      return firstName + "" + lastName;
    } else {
      return firstName;
    }
  }

  let tomcat = buildName("Tom", "Cat");
  let tom = buildName("Tom");
}

// default for argument
{
  function buildName(firstName: string, lastName: string = "Cat") {
    return firstName + "" + lastName;
  }

  let tomcat = buildName("Tom", "Cat");
  let tom = buildName("Tom");
}

// rest arguments
{
  function push(array: any[], ...items: any[]) {
    items.forEach(function (item) {
      array.push(item);
    });
  }

  let a: any[] = [];
  push(a, 1, 2, 3);
}

// overloading
{
  function reverse(x: number): number;
  function reverse(x: string): string;
  function reverse(x: number | string): number | string | void {
    if (typeof x === "number") {
      return Number(x.toString().split("").reverse().join(""));
    } else if (typeof x === "string") {
      return x.split("").reverse().join("");
    }
  }

  console.log(reverse(123));
  console.log(reverse("456"));
}
